#include "capture.h"

Capture::Capture()
{
    bCapture = true;
}
Capture::Capture(char *interface){
    bCapture = true;
    SetInterface(interface);
}
Capture::~Capture(){
    delete packet_content;
    delete net_interface;
}

void Capture::StartCapture(){
    char error_content[PCAP_ERRBUF_SIZE];
    struct pcap_pkthdr protocol_header;
    pcap_t *pcap_handle;
    bpf_u_int32 net_mask;
    bpf_u_int32 net_ip;
    struct ether_header *eptr;          //以太网帧

    printf("Capture a packet from : %s\n", net_interface);
    pcap_lookupnet(net_interface, &net_ip, &net_mask, error_content);
    pcap_handle = pcap_open_live(net_interface, BUFSIZ, 1, 0, error_content);
    while(bCapture){
        packet_content = pcap_next(pcap_handle,&protocol_header) ;
        eptr=(struct ether_header *)packet_content;
        if(ntohs(eptr->ether_type)==ETHERTYPE_IP)
        CaptureHttpPackage();
    }
    pcap_close(pcap_handle);
}

void Capture::SetInterface(char *interface){
    net_interface = interface;
}

void Capture::CaptureHttpPackage(){
    int http_len;
    struct iphdr *ipptr;                     //ip数据报
   // struct in_addr addr;
    struct tcphdr *tcpptr;                 //tcp
    char *data;
    char httpbuf[2000];
    char hostbuf[500];
    char getbuf[100];
    char url[100];

    ipptr=(struct  iphdr *)(packet_content+sizeof(struct ether_header));//获得ip数据报的内存地值
    cur_package.SetIpHead(ipptr);
    if(ipptr->protocol==6)        //筛选出tcp报文
    {
        tcpptr=(struct tcphdr *)(packet_content+sizeof(struct ether_header)+sizeof(struct iphdr));
        if(htons(tcpptr->dest)==80)//拦截向外输出的数据
        {
            printf("\nSoure IP %s\n",cur_package.GetSrcAddr());
            printf("Destination IP %s\n",cur_package.GetDstAddr());
            printf("IP length:%d\n",cur_package.GetLength());

            data=(char *)(packet_content+sizeof(struct ether_header)+sizeof(struct iphdr)+sizeof(struct tcphdr));

            http_len=ntohs(ipptr->tot_len) - ( ipptr->ihl )*4 - sizeof(struct tcphdr);
            if(http_len>0)
                if( (*data=='G') && (*++data=='E') && (*++data=='T') )
                {
                    memcpy(httpbuf,data-2,http_len);
                    *(httpbuf+http_len)='\0';
                    GetHost(httpbuf,hostbuf);

                    GetGet(httpbuf,getbuf);

                    GetUrlPage(getbuf,url);
                    printf("Url:%s\n",url);
                    printf("This is %s page\n",IsRealPage(url)>0 ? "real":"not");
                }
        }
    }
}

int Capture::GetGet(char *data, char *buff){
    int i=0;
    if(data==NULL) return 0;

    while(*data!='\r')
    {
        if(*data==' ')
            i++;
        if(i!=2)
        {
            *buff++=*data++;
        }
        else
        {
            *buff='\0';
            return 1;
        }
    }
    return 0;
}

int Capture::GetUrlPage(char *data, char *buff){
    if(data==NULL) return 0;
    data+=4;//去掉前面"get "

    while(*data!='\0')
    {
        if(*data!='?')
        {
            *buff++=*data++;
        }
        else
        {
            *buff='\0';
            return 1;
        }
    }
    *buff='\0';
    return 1;
}

int Capture::IsRealPage(char *data){
    if(data==NULL)
        return -1;
    while(*data!='\0')//指针移动URL最后
    {
        data++;
    }

    while(*--data!='/')//eg: com/fgfg.asp?eeet=yuyuu; com/jjj?ddd=123
    {
        if(*data=='.')
        {
            switch(*++data)
            {
            case 'a':
                if((*++data=='s') && (*++data=='p'))
                    return 1;//asp,aspx
                return 0;
            case 'h':if((*++data=='t') && (*++data=='m')) return 1;return 0;//htm,html
            case 'j':if((*++data=='s') && (*++data=='p')) return 1;return 0;//jsp
            case 'p':if((*++data=='h') && (*++data=='p')) return 1;return 0;//php
            default:return 0;
            }
        }
    }
    return 1;
}

int Capture::GetHost(char *data, char *buff){
    if(data==NULL) return 0;
    while(data!='\0')
    {
        if((*data=='H') && (*++data=='o') &&(*++data=='s') &&(*++data=='t'))
        {
            data++;//去掉http请求头标中键值对的‘:’
            while(*data!='\r')//while((*data!='\r')&&(*++data!='\n'))
            {
                *buff++=*++data;
            }
            *buff='\0';
            return 1;
        }
        data++;
    }
    return 0;
}
